﻿#ifndef UIM_H
#define UIM_H

#include <qlibrary.h>

#include "tool.h"
#include "UISimCanFunc_RT.h"

#define NODEIDLEFT 5
#define NODEIDRIGHT 6
#define NODEIDFORBACK 7
#define NODEIDPUSH 8
#define ENCODEMODE 2

/************************************************************************************
UIM 电机配置                     ID  电机转向    细分      电流      S1-IN       S2-IN
胶片扫描控制
    Left    左卷电机-编码         5     1        16       1.5
    Right   右卷电机-编码         6     0        16       1.5
    ForBack 前后电机-限位         7     1        16       1.5         1          2

上电状态控制寄存器-CCW电机转向：1，0，1，0，1，1，1，1
主配置寄存器：AM加速度：1，DM减速度：1；通知(原点、位移、P3、S3、S2、S1)：1，1，1，1，1，1
S12CON寄存器：无动作，有通知；
    电机运动按钮：按钮1-S1方向运动，按钮2-S2方向运动；
    传感变化通知：上升沿-IN，下降沿-OUT；S1 靠电机方向，S2 为原点；
    传感通知程序： S1-IN:  S1=true，电机停止，反向运动；
                 S1-OUT: 无动作
                 S2-IN:  S2=true，电机停止，反向运动；
                 S2-OUT: 无动作
                 MOVE：   如果S2,设置原点，S2=false；如果S1,S1=false；
异常问题：频繁变化通知，传感器问题，导致电机频繁原地运动；调焦电机驱动电流0.1A,写入，关电后，重新复位0.1；关电出现上下电机原点消失；
********************************************************************************************/

typedef struct _UIM_PARA
{
    int             bENA;           //电机使能状态
    int             bDIR;           //电机方向
    int             bACR;           //电流减半
    unsigned int    uiMCS;          //电机细分
    unsigned int    uiCUR;          //电流
    int             uiSPD;          //当前速度
    int             uiSTP;          //当前步长
}UIM_PARA;


class UIM
{

public:
    UIM(const QString name,int usb,int com);
    ~UIM();
    int ret;

    void Init(void);

    bool isOpen(void);
    int getIndex(void);
    QStringList getList(void);

    // CAN 函数
    void canSearch(void);
    static int compare(const void *first, const void *second);
    bool canOpenGateWay(void);
    void canCloseGateWay(void);

    bool canEna(bool &en,int id, const QString msg="", UIM_PARA *para = nullptr);
    bool canOff(bool &en,int id, const QString msg="", UIM_PARA *para = nullptr);
    //左卷片
    void canLeftEna(bool en=false);
    void canLeftOff(bool en=false);
    int getLeftId(void);
    int getLeftPos(void);
    int getLeftQec(void);
    bool isLeftId(int id=0);
    bool isLeft(void);
    bool getCanLeftMove(void);
    void setCanLeftMove(bool mv=false);
    //编码
    int getEncodeLeft(bool Qec);
    int getEncodeRight(bool Qec);
    //右卷片
    void canRightEna(bool en=false);
    void canRightOff(bool en=false);
    int getRightId(void);
    int getRightPos(void);
    int getRightQec(void);
    bool isRightId(int id=0);
    bool isRight(void);
    bool getCanRightMove(void);
    void setCanRightMove(bool mv=false);
    //前后卷片
    void canForBackEna(bool en=false);
    void canForBackOff(bool en=false);
    int getForBackId(void);
    bool isForBackId(int id=0);
    bool isForBack(void);
    int getForBackPos(void);
    int getCanForBackMove(void);
    void setCanForBackMove(int mv);
    int getForBackStep(void);

    bool getCanForBack1(void);
    void setCanForBack1(bool in);
    bool getCanForBack2(void);
    void setCanForBack2(bool in);
    int getCanForBackRevStep(void);
    void setCanForBackRevStep(int step);
    //压片
    void canPushEna(bool en=false);
    void canPushOff(bool en=false);
    int getPushId(void);
    bool isPushId(int id=0);
    bool isPush(void);
    int getPushPos(void);
    int getCanPushMove(void);
    void setCanPushMove(int mv);
    int getPushStep(void);

    bool getCanPush1(void);
    void setCanPush1(bool in);
    bool getCanPush2(void);
    void setCanPush2(bool in);
    int getCanPushRevStep(void);
    void setCanPushRevStep(int step);
    //电机移动
    void canSetSPD(int index,int spd);
    void canSetSTP(int index,int stp);
    void canStop(int index);
    void canSetOrg(int index);
    int canGetPos(int index);
    void canSetPOS(int index,int pos);
    void canSetQec(int index);
    int canGetQec(int index);
    //寄存器
    UIM_PARA *getLeftPara(void);
    UIM_PARA *getRightPara(void);
    UIM_PARA *getForBackPara(void);

//    bool canGetAck(int index,int &Mcs,int &Cur);
//    int canGetMcs(int index);
//    int canGetCur(int index);
//    int canSetMcs(int index, int mcs);
//    int canSetCur(int index, int cur);
    // bool isCanSet(const int id);

private:
    UIM_PARA canLeftPara;
    UIM_PARA canRightPara;
    UIM_PARA canForBackPara;
    UIM_PARA canPushPara;

    int usbPort;
    int comPort;
    //CAN变量
    int canGatewayCount;
    unsigned int canCurGatewayIndex;
    bool isCanGateway;
    unsigned int canGatewayIndex[5];
    QStringList canGatewayNameList;
    int canNodeLen;

    //左收片+编码
    bool isCanLeftEnable;
    int canLeftNodeId;
    bool isCanLeftMove;
    //右收片+编码
    bool isCanRightEnable;
    int canRightNodeId;
    bool isCanRightMove;
    //前后
    bool isCanForBackEnable;
    int canForBackNodeId;
    bool isCanForBackS1;
    bool isCanForBackS2;
    int isCanForBackMove;
    bool isCanForBackMoveType;
    int canForBackStep;
    int canForBackPos;
    //停止运动后反向运动
    int canForBackRevStep;
    //压片
    bool isCanPushEnable;
    int canPushNodeId;
    bool isCanPushS1;
    bool isCanPushS2;
    int isCanPushMove;
    bool isCanPushMoveType;
    int canPushStep;
    int canPushPos;
    //停止运动后反向运动
    int canPushRevStep;
};

#endif // UIM_H
